#ifndef __STL_VECTOR_STORAGE__
#define __STL_VECTOR_STORAGE__
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cassert> // 需要添加这个头文件
#include <initializer_list>

namespace STL
{
    template <class T>
    class vector
    {
    public:
        using iterator = T *;
        using const_iterator = const T *;

    public:
        // 构造函数
        vector() {}

        vector(size_t n, T val = T())
        {
            reserve(n);
            for (size_t i = 0; i < n; i++)
                push_back(val);
        }

        vector(int n, T val = T())
        {
            reserve(n);
            for (int i = 0; i < n; i++)
                push_back(val);
        }

        template <class InputIterator>
        vector(InputIterator first, InputIterator last)
        {
            for (InputIterator it = first; it != last; it++)
                push_back(*it);
        }

        vector(const vector<T> &tmp)
        {
            for (const_iterator it = tmp.begin(); it != tmp.end(); it++)
                push_back(*it);
        }

        vector(std::initializer_list<T> il)
        {
            for (auto it = il.begin(); it < il.end(); it++)
                push_back(*it);
        }

        vector(vector<T> &&tmp)
        {
            swap(tmp);
            std::cout << "移动构造被调用！" << std::endl;
        }

        vector<T> &operator=(vector<T> tmp)
        {
            std::cout << "移动赋值被调用！" << std::endl;
            swap(tmp);
            return *this;
        }

        void swap(vector<T> &tmp)
        {
            std::swap(_start, tmp._start);
            std::swap(_end, tmp._end);
            std::swap(_storage, tmp._storage);
        }

        // 扩容
        void reserve(size_t n)
        {
            if (n > capacity())
            {
                T *_data = new T[n];
                size_t oldsize = size();
                if (oldsize > 0)
                {
                    // memcpy(_data, _start, oldsize * sizeof(T));//浅拷贝,内存访问空间无效
                    for (size_t i = 0; i < oldsize; i++)
                        _data[i] = _start[i];
                }
                delete[] _start;
                _start = _data;
                _end = _start + oldsize;
                _storage = _start + n;
            }
        }

        void resize(size_t n, T val = T())
        {
            // 尺寸比当前要小
            size_t oldsize = size();
            if (n <= oldsize)
            {
                _end = _start + n;
            }
            else
            {
                // 尺寸比当前要大
                reserve(n);
                size_t deffer = n - oldsize;
                for (size_t i = 0; i < deffer; i++)
                    push_back(val);
            }
        }

        void push_back(const T &val)
        {
            insert(end(), val);
        }

        template <class... Args>
        void emplace_back(Args &&...args)
        {
            std::cout << "移动emplace_back...." << std::endl;
            if (_end == _storage)
            {
                reserve(capacity() == 0 ? 4 : 2 * capacity());
            }
            insert(_end, std::forward<Args>(args)...);
            ++_end;
        }

        template <class... Args>
        iterator insert(iterator pos, Args &&...args)
        {
            std::cout << "移动 insert...." << std::endl;
            assert(pos >= _start && pos <= _end);
            // 空间不够先扩容
            if (_end == _storage)
            {
                size_t offset = pos - _start;
                int n = (capacity() == 0 ? 4 : 2 * capacity());
                reserve(n);
                pos = _start + offset;
            }
            // 空间足够压入元素
            for (iterator it = _end - 1; it >= pos; it--)
            {
                *(it + 1) = *it;
            }
            new (pos) T(std::forward<Args>(args)...);
            _end += 1;
            return pos;
        }

        iterator insert(iterator pos, T &&val)
        {
            std::cout << "移动insert...." << std::endl;
            assert(pos >= _start && pos <= _end);
            // 空间不够先扩容
            if (_end == _storage)
            {
                size_t offset = pos - _start;
                int n = (capacity() == 0 ? 4 : 2 * capacity());
                reserve(n);
                pos = _start + offset;
            }
            // 空间足够压入元素
            for (iterator it = _end - 1; it >= pos; it--)
            {
                *(it + 1) = *it;
            }
            *(pos) = std::move(val);
            _end += 1;
            return pos;
        }

        iterator find(const T &val)
        {
            for (iterator it = begin(); it != end(); it++)
            {
                if (*it == val)
                    return it;
            }
            return end();
        }

        iterator insert(iterator pos, const T &val)
        {
            assert(pos >= _start && pos <= _end);
            // 空间不够先扩容
            if (_end == _storage)
            {
                size_t offset = pos - _start;
                int n = (capacity() == 0 ? 4 : 2 * capacity());
                reserve(n);
                pos = _start + offset;
            }
            // 空间足够压入元素
            for (iterator it = _end - 1; it >= pos; it--)
            {
                *(it + 1) = *it;
            }
            *(pos) = val;
            _end += 1;
            return pos;
        }

        void pop_back()
        {
            if (!empty())
                --_end;
        }

        iterator erase(iterator pos)
        {
            if (pos < _start || pos >= _end)
                return end();

            for (iterator it = pos; it < _end - 1; ++it)
            {
                *it = *(it + 1);
            }
            --_end;
            return pos;
        }

        bool empty()
        {
            return _start == _end;
        }

        // 测试当都为nullptr,输出0
        size_t capacity()
        {
            return _storage - _start;
        }

        size_t size()
        {
            return _end - _start;
        }

        T &operator[](const size_t n)
        {
            return *(_start + n);
        }

        const T &operator[](size_t n) const
        {
            return *(_start + n);
        }

        iterator end()
        {
            return _end;
        }

        iterator begin()
        {
            return _start;
        }

        const_iterator end() const
        {
            return _end;
        }

        const_iterator begin() const
        {
            return _start;
        }

        void print()
        {
            for (auto it = begin(); it != end(); it++)
            {
                std::cout << *it << " ";
            }
            std::cout << "size: " << size() << " " << "cap: " << capacity();
            std::cout << std::endl;
        }

        ~vector()
        {
            if (_start)
                delete[] _start;
        }

    private:
        iterator _start = nullptr;
        iterator _end = nullptr;
        iterator _storage = nullptr;
    };
}

#endif